package nbcp.base.utils

import nbcp.base.comm.MvnDependencyBasicData
import nbcp.base.extend.*
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import java.io.File
import java.net.URL
import java.time.LocalDateTime
import java.util.*
import java.util.jar.JarFile

object JarUtil {
    private val logger = LoggerFactory.getLogger(this::class.java)

    /**
     * 获取启动主类
     */
    val startMainClass: Class<*> by lazy {
        var startClasses = SpringUtil.context.getBeansWithAnnotation(SpringBootApplication::class.java);
        if (startClasses.any() == false) {
            throw RuntimeException("找不到带有 @SpringBootApplication 注解的启动类！")
        }
        return@lazy startClasses.values.first().javaClass
    }

    val startJarPackage: String
        get() {
            return startMainClass.packageName
        }


    fun getJarExePath(): String {
        val osName = System.getProperty("os.name").lowercase(Locale.getDefault())
        var javaHomePath = System.getProperty("java.home")

        //修复！
        if (javaHomePath.endsWith("jre")) {
            javaHomePath = FileUtil.resolvePath(javaHomePath, "../")
        }
        var jarExePath = FileUtil.resolvePath(javaHomePath, "bin", "jar")
        if (osName.contains("windows")) {
            jarExePath += ".exe"
        }
        if (File(jarExePath).exists() == false) {
            throw RuntimeException("找不到 jar 命令：$jarExePath")
        }
        return jarExePath
    }

    /**
     * 获取启动Jar所的路径
     */
    @JvmStatic
    fun getStartingJarFile(): File {

        var startJar = startMainClass.protectionDomain.codeSource.location.path;

        //file:/app/mp-admin-api-1.0.1-split-jar.jar!/BOOT-INF/classes!/
        if (startJar.endsWith("!/BOOT-INF/classes!/")) {
            startJar = startJar.substring(0, startJar.length - "!/BOOT-INF/classes!/".length)
        }

        if (startJar.startsWith("file:///")) {
            startJar = startJar.substring("file://".length)
        }

        if (startJar.startsWith("file:/")) {
            startJar = startJar.substring("file:".length)
        }

        return File(startJar)
    }


    /**
     * 从外部Jar包获取元数据信息
     */
    fun getJarMetaInfo(file: File): MvnDependencyBasicData {
        return JarFile(file)
            .use { jarFile ->
                val entries = jarFile.entries()
                while (entries.hasMoreElements()) {
                    val jarEntry = entries.nextElement()
                    if (jarEntry.isDirectory) {
                        continue
                    }
                    if (jarEntry.name.startsWith("META-INF/maven")
                        && jarEntry.name.endsWith("/pom.properties")
                    ) {


                        return@use getGroupIdFromPomProperties(jarFile.getInputStream(jarEntry).readContentString())

                    }
                }
                return@use MvnDependencyBasicData();
            }
    }

    private fun getGroupIdFromPomProperties(content: String): MvnDependencyBasicData {
        var ret = MvnDependencyBasicData();
        val lines = content.split("\n".toRegex()).toTypedArray()
        for (line in lines) {
            var kv = line.split("=");
            if (kv.size == 1) {
                content;
            }

            if (kv[0] == "groupId") {
                ret.groupId = kv[1].trim();
            } else if (kv[0] == "artifactId") {
                ret.artifactId = kv[1].trim();
            } else if (kv[0] == "version") {
                ret.version = kv[1].trim();
            }
        }
        return ret
    }
}